package com.game.core.res
{
	import br.com.stimuli.loading.BulkLoader;
	
	import flash.utils.Dictionary;

	public class ResourceManager
	{
		private var _notifyInitCompleted : Function;	
		public var bulkLoader : BulkLoader;	
		public var id2ResDescription : Dictionary;	
		public var id2Resource : Dictionary;
		private var _compress2cryptExtensions : Array;
		
		private static var _instance : ResourceManager;
		public static function getInstance() : ResourceManager
		{
			if (!_instance)
			{
				_instance = new ResourceManager();
			}
			return _instance;
		}
		
		public function ResourceManager()
		{
			bulkLoader = new BulkLoader('ResourceManager' , 2);
			id2ResDescription = new Dictionary();
			id2Resource = new Dictionary();
			_compress2cryptExtensions = [];
		}
		
		public function init(fileSystemURL : String, notifyCompleted : Function) : void
		{            
			_notifyInitCompleted = notifyCompleted;
			
			Resource.getResource(fileSystemURL)
			.onComplete(loadFileSystemSuccess)
				.onIOError(loadFileSystemFailed)
				.load();
			
//			startBulkIfNeed();
		}
		
		private function loadFileSystemSuccess(res:GameResource):void
		{
			var xml:XML = res.getXml();
			parse(xml);		
			invokeInitCompleted(true);
			res.unload();
		}
		
		private function loadFileSystemFailed(res:GameResource):void
		{
			invokeInitCompleted(false);
		}
		
		private function invokeInitCompleted(success : Boolean) : void
		{
			if (_notifyInitCompleted != null)
			{
				_notifyInitCompleted(success);
				_notifyInitCompleted = null;
			}
		}
		
		public function getResource(id:String):GameResource
		{
			return id2Resource[id];
		}
		
		public function createResource(id:String):GameResource
		{
			var res : GameResource = id2Resource[id];
			if (!res)
			{
				res = new GameResource(id);
				var desc : ResourceDescription = id2ResDescription[id];
				if(desc)
				{
					res.version = desc.version;
				}
				res.url = desc?desc.url:id;
				id2Resource[id] = res;
			}
			
			if(isCompress2cryptType(res.url))
				res.type(BulkLoader.TYPE_BINARY).attr["compress2crypt"] = true;
					
			return res;
		}
	
		public function addCompress2cryptExtensions(extension : String): ResourceManager
		{
			var index : int = _compress2cryptExtensions.indexOf(extension);
			if(index == -1)
				_compress2cryptExtensions.push(extension);
			return this;
		}
		
		private function isCompress2cryptType(urlAsString:String):Boolean
		{
			var searchString : String = urlAsString.indexOf("?") > -1 ? 
				urlAsString.substring(0, urlAsString.indexOf("?")) : 
				urlAsString;
			// split on "/" as an url can have a dot as part of a directory name
			var finalPart : String = searchString.substring(searchString.lastIndexOf("/"));;
			var extension : String = finalPart.substring(finalPart.lastIndexOf(".") + 1).toLowerCase();
			for each(var checkExt : String in _compress2cryptExtensions)
			{
				if(checkExt == extension)
					return true;
			}
			return false;
		}
		
		public function clearResource(id : String):void
		{
			if(id2Resource[id] != null)
			{
				id2Resource[id] = null;
				delete id2Resource[id];
			}
		}
		
		public function parse(xml : XML) : void
		{
			for each (var file : XML in xml.file)
			{
				var desc : ResourceDescription = new ResourceDescription();
				desc.id  = String(file.@id);
				desc.url = String(file.@url);
				desc.version = String(file.@version);
				id2ResDescription[desc.id] = desc;
			}
		}
		
	}
}